function r = mirr(cf, srate, rrate)
%MIRR Modified internal rate of return for a series of periodic cash flows.
%
%   R = mirr(CF, SRATE, RRATE)
%
%   Inputs:
%      CF - Scalar or vector of the cash flow. If CF is entered as a matrix, 
%           each column is treated as a separate cash flow.
%
%   SRATE - Scalar or vector of the finance rate for negative cash flow values.
%
%   RRATE - Scalar or vector of the reinvestment rate for positive cash flow
%           values.
%
%   Note: SRATE and RRATE can be entered as row vectors where each column
%         corresponds to a column of CF, or as scalars that apply the
%         same rate to each cash flow.
%
%   Outputs:
%       R - Scalar or vector of the modified internal rate of return.
%
%   Example:
%      Suppose an initial investment of $100,000 is made. The following
%      cash flow represents the yearly income realized by the investment.
%      The finance rate is 9% and the reinvestment rate is 12%.
%
%                 Year 1       $20,000
%                 Year 2      ($10,000)
%                 Year 3       $30,000
%                 Year 4       $38,000
%                 Year 5       $50,000
%
%      r = mirr([-100000 20000 -10000 30000 38000 50000], 0.09, 0.12)
%
%      r = 0.0832 or 8.32%
%
%   See also ANNURATE, IRR, PVVAR, XIRR.
  
%       Copyright 1995-2006 The MathWorks, Inc.
%       $Revision: 1.6.2.4 $   $Date: 2009/05/07 18:23:30 $ 

%   Reference: Brealey and Myers, Principles of Corporate Finance,
%              Chapter 5.
 
% Input validation
if nargin < 3
    error('Finance:mirr:notEnoughInputs', 'Too few inputs.')
end

if ~isnumeric(cf)
   error('finance:mirr:invalidInputArg','Invalid CF input.')
end

if ~isnumeric(srate)
   error('finance:mirr:invalidInputArg','Invalid SRATE input.')
end

if ~isnumeric(rrate)
   error('finance:mirr:invalidInputArg','Invalid RRATE input.')
end

if srate < 0 | rrate < 0 %#ok
    error('Finance:mirr:notEnoughInputs', 'SRATE and RRATE must be >= 0.')
end

if isempty(cf) || isempty(srate) || isempty(rrate)
    r = [];
    return
end

[rowcf, colcf] = size(cf);

if rowcf == 1
    cf = cf(:);
    colcf = 1;
end

% Scalar expand rates
if colcf > 1
    if length(srate) == 1
        srate = srate*ones(1, colcf);
    end

    if length(rrate) == 1
        rrate = rrate*ones(1, colcf);
    end
end


for loop = 1:colcf
    cflow = cf(:, loop);
    % Create separate negative and positive cash flows
    neg = find(cflow > 0);
    pos = find(cflow < 0);
    cfn = cflow;
    cfp = cflow;
    cfn(neg) = zeros(size(neg));
    cfp(pos) = zeros(size(pos));

    % PV of neg cash flow
    pvcfn = pvvar(cfn, srate(loop));

    % FV of positive cash flow FV = PV*(1+r)^n
    pvcfp = pvvar([0;cfp], rrate(loop))*(1+rrate(loop))^(length(cfp(:)));

    % Solve for for ror
    r(loop) = annurate(length(cflow)-1, 0, pvcfn, pvcfp, 1);
end  % End for loop


% [EOF]
